﻿<TemplatePart(Name:=FlipPanel.LayoutRoot_ElementName, Type:=GetType(FrameworkElement))> _
<TemplatePart(Name:=FlipPanel.FrontContentPresenter_ElementName, Type:=GetType(FrameworkElement))> _
<TemplatePart(Name:=FlipPanel.BackContentPresenter_ElementName, Type:=GetType(FrameworkElement))> _
<TemplatePart(Name:=FlipPanel.FlipButton_ElementName, Type:=GetType(FrameworkElement))> _
Public Class FlipPanel
	Inherits Control

	Public Const LayoutRoot_ElementName As String = "LayoutRoot"
	Public Const FlipButton_ElementName As String = "FlipButton"
	Public Const FrontContentPresenter_ElementName As String = "FrontContentPresenter"
	Public Const BackContentPresenter_ElementName As String = "BackContentPresenter"

	Public Enum Sides
		Front
		Back
	End Enum

	Private _LayoutRoot As FrameworkElement = Nothing
	Private _FlipButton As FrameworkElement = Nothing
	Private _FrontContentPresenter As FrameworkElement = Nothing
	Private _BackContentPresenter As FrameworkElement = Nothing

	Private _ControlUpdating As Boolean = False

	Public Sub New()
		MyBase.New()
		MyBase.DefaultStyleKey = GetType(FlipPanel)
	End Sub

	Public Overrides Sub OnApplyTemplate()
		MyBase.OnApplyTemplate()
		UpdateControl()
	End Sub

	Private Sub UpdateControl()
		If _ControlUpdating Then Exit Sub
		_ControlUpdating = True

		If _LayoutRoot Is Nothing Then _LayoutRoot = TryCast(GetTemplateChild(LayoutRoot_ElementName), FrameworkElement)
		If _LayoutRoot IsNot Nothing Then
			Dim element As Grid = TryCast(_LayoutRoot, Grid)
			If element IsNot Nothing Then
				' Update LayoutGrid here.  
			End If
		End If
		If _FlipButton Is Nothing Then _FlipButton = TryCast(GetTemplateChild(FlipButton_ElementName), FrameworkElement)
		If _FlipButton IsNot Nothing Then
			Dim element As Button = TryCast(_FlipButton, Button)
			If element IsNot Nothing Then
				' Update Button
				RemoveHandler element.Click, AddressOf _FlipButton_Click
				AddHandler element.Click, AddressOf _FlipButton_Click
			End If
		End If
		If _FrontContentPresenter Is Nothing Then _FrontContentPresenter = TryCast(GetTemplateChild(FrontContentPresenter_ElementName), FrameworkElement)
		If _FrontContentPresenter IsNot Nothing Then
			Dim element As ContentPresenter = TryCast(_FrontContentPresenter, ContentPresenter)
			If element IsNot Nothing Then
				' Update FrontContentPresenter here.
				If Side = Sides.Front Then
					element.Visibility = Windows.Visibility.Visible
				Else
					element.Visibility = Windows.Visibility.Collapsed
				End If
			End If
		End If
		If _BackContentPresenter Is Nothing Then _BackContentPresenter = TryCast(GetTemplateChild(BackContentPresenter_ElementName), FrameworkElement)
		If _BackContentPresenter IsNot Nothing Then
			Dim element As ContentPresenter = TryCast(_BackContentPresenter, ContentPresenter)
			If element IsNot Nothing Then
				' Update BackContentPresenter here.  
				If Side = Sides.Front Then
					element.Visibility = Windows.Visibility.Collapsed
				Else
					element.Visibility = Windows.Visibility.Visible
				End If
			End If
		End If


		_ControlUpdating = False
	End Sub

	Private Sub _FlipButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
		Select Case Side
			Case Sides.Front
				Side = Sides.Back
			Case Sides.Back
				Side = Sides.Front
			Case Else
				Throw New ArgumentOutOfRangeException("Side")
		End Select
		UpdateControl()
	End Sub

	Private Sub FlipPanel_LayoutUpdated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LayoutUpdated
		UpdateControl()
	End Sub

#Region " FrontDataTemplateProperty Dependency Property "

#Region " FrontDataTemplate Property "

	Public Property FrontDataTemplate() As StackPanel
		Get
			Return DirectCast(GetValue(FrontDataTemplateProperty), StackPanel)
		End Get
		Set(ByVal value As StackPanel)
			SetValue(FrontDataTemplateProperty, value)
		End Set
	End Property

#End Region

#Region " FrontDataTemplate Dependency Property "

	Public Shared ReadOnly FrontDataTemplateProperty As DependencyProperty = DependencyProperty.Register("FrontDataTemplate", GetType(StackPanel), GetType(FlipPanel), New PropertyMetadata(Nothing, AddressOf OnFrontDataTemplatePropertyChanged))

#End Region

#Region " FrontDataTemplate Property Changed CallBack "

	Private Shared Sub OnFrontDataTemplatePropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
		If e.OldValue Is Nothing AndAlso e.NewValue Is Nothing Then Exit Sub
		If e.OldValue IsNot Nothing AndAlso e.OldValue.Equals(e.NewValue) Then Exit Sub

		Dim source As FlipPanel = TryCast(d, FlipPanel)
		If source Is Nothing Then Throw New ArgumentException("source is not an instance of FlipPanel!")

		' Provide any other validation here.

		' Apply any other changes here.

	End Sub

#End Region

#End Region

#Region " BackDataTemplateProperty Dependency Property "

#Region " BackDataTemplate Property "

	Public Property BackDataTemplate() As UIElement
		Get
			Return DirectCast(GetValue(BackDataTemplateProperty), UIElement)
		End Get
		Set(ByVal value As UIElement)
			SetValue(BackDataTemplateProperty, value)
		End Set
	End Property

#End Region

#Region " BackDataTemplate Dependency Property "

	Public Shared ReadOnly BackDataTemplateProperty As DependencyProperty = DependencyProperty.Register("BackDataTemplate", GetType(UIElement), GetType(FlipPanel), New PropertyMetadata(Nothing, AddressOf OnBackDataTemplatePropertyChanged))

#End Region

#Region " BackDataTemplate Property Changed CallBack "

	Private Shared Sub OnBackDataTemplatePropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
		If e.OldValue Is Nothing AndAlso e.NewValue Is Nothing Then Exit Sub
		If e.OldValue IsNot Nothing AndAlso e.OldValue.Equals(e.NewValue) Then Exit Sub

		Dim source As FlipPanel = TryCast(d, FlipPanel)
		If source Is Nothing Then Throw New ArgumentException("source is not an instance of FlipPanel!")

		' Provide any other validation here.

		' Apply any other changes here.

	End Sub

#End Region

#End Region

#Region " SideProperty Dependency Property "

#Region " Side Property "

	Public Property Side() As Sides
		Get
			Return DirectCast(GetValue(SideProperty), Sides)
		End Get
		Set(ByVal value As Sides)
			SetValue(SideProperty, value)
		End Set
	End Property

#End Region

#Region " Side Dependency Property "

	Public Shared ReadOnly SideProperty As DependencyProperty = DependencyProperty.Register("Side", GetType(Sides), GetType(FlipPanel), New PropertyMetadata(Sides.Front, AddressOf OnSidePropertyChanged))

#End Region

#Region " Side Property Changed CallBack "

	Private Shared Sub OnSidePropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
		If e.OldValue Is Nothing AndAlso e.NewValue Is Nothing Then Exit Sub
		If e.OldValue IsNot Nothing AndAlso e.OldValue.Equals(e.NewValue) Then Exit Sub

		Dim source As FlipPanel = TryCast(d, FlipPanel)
		If source Is Nothing Then Throw New ArgumentException("source is not an instance of FlipPanel!")

		' Provide any other validation here.

		' Apply any other changes here.

	End Sub

#End Region

#End Region

End Class
